{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 特征整合"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将所有特征串联起来，构成RS_Train.csv和RS_Test.csv，为最后推荐系统做准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入工具包\n",
    "from __future__ import division\n",
    "\n",
    "import pickle\n",
    "import numpy as np\n",
    "import scipy.io as sio\n",
    "import scipy.sparse as ss\n",
    "from numpy.random import random  \n",
    "from collections import defaultdict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义推荐系统类\n",
    "class RecommonderSystem:\n",
    "    def __init__(self):\n",
    "        # 读入数据做初始化\n",
    "        \n",
    "        ## 定义用户和活动索引\n",
    "        self.userIndex = pickle.load(open('PE_userIndex.pkl', 'rb'))\n",
    "        self.eventIndex = pickle.load(open('PE_eventIndex.pkl', 'rb'))\n",
    "        ## 定义用户和活动数量\n",
    "        self.n_users = len(self.userIndex)\n",
    "        self.n_events = len(self.eventIndex)\n",
    "        ## 定义用户活动关系矩阵R\n",
    "        self.userEventScores = sio.mmread(\"PE_userEventScores\").todense()\n",
    "        \n",
    "        ## 每个用户参加的事件\n",
    "        self.eventsForUser = pickle.load(open(\"PE_eventsForUser.pkl\", 'rb'))\n",
    "        ## 每个事件有哪些用户参加\n",
    "        self.usersForEvent = pickle.load(open(\"PE_usersForEvent.pkl\", 'rb'))\n",
    "        \n",
    "        ## 基于模型的协同过滤参数初始化,训练\n",
    "        self.init_SVD()\n",
    "        self.train_SVD(trainfile = \"/Users/cuiyue/Desktop/AI/第四周/作业/要求/71-57-1-1519640547/train.csv\")\n",
    "        \n",
    "        ## 根据用户属性计算出的用户之间的相似度\n",
    "        self.userSimMatrix = sio.mmread(\"US_userSimMatrix\").todense()\n",
    "        \n",
    "        ## 根据活动属性计算出的活动之间的相似度\n",
    "        self.eventPropSim = sio.mmread(\"EV_eventPropSim\").todense()\n",
    "        self.eventContSim = sio.mmread(\"EV_eventContSim\").todense()\n",
    "        \n",
    "        ## 每个用户的朋友的数目\n",
    "        self.numFriends = sio.mmread(\"UF_numFriends\")\n",
    "        ## 用户的每个朋友参加活动的分数对该用户的影响\n",
    "        self.userFriends = sio.mmread(\"UF_userFriends\").todense()\n",
    "        \n",
    "        ## 活动本身的热度\n",
    "        self.eventPopularity = sio.mmread(\"EA_eventPopularity\").todense()\n",
    "    \n",
    "    def init_SVD(self, k = 20):\n",
    "        #初始化模型参数（for 基于模型的协同过滤SVD_CF）\n",
    "        self.k = k  \n",
    "        #init parameters\n",
    "        #bias\n",
    "        self.bi = np.zeros(self.n_events)  \n",
    "        self.bu = np.zeros(self.n_users)  \n",
    "        \n",
    "        #the small matrix\n",
    "        #用符合正态分布的随机数X~N(0,1)来填充PQ矩阵.\n",
    "        self.P = random((self.n_users,self.k))/10*(np.sqrt(self.k)) # np.sqrt开平方根\n",
    "        self.Q = random((self.k, self.n_events))/10*(np.sqrt(self.k))  \n",
    "        \n",
    "    def train_SVD(self,trainfile = '/Users/cuiyue/Desktop/AI/第四周/作业/要求/71-57-1-1519640547/train.csv', steps=100,gamma=0.04,Lambda=0.15):\n",
    "        \n",
    "        #训练SVD模型（for 基于模型的协同过滤SVD_CF）\n",
    "        #gamma：为学习率\n",
    "        #Lambda：正则参数\n",
    "\n",
    "        #偷懒了，为了和原来的代码的输入接口一样，直接从训练文件中去读取数据\n",
    "        print(\"SVD Train...\")\n",
    "        ftrain = open(trainfile, 'r')\n",
    "        ftrain.readline()\n",
    "        self.mu = 0.0\n",
    "        n_records = 0\n",
    "        uids = []  #每条记录的用户索引\n",
    "        i_ids = [] #每条记录的item索引\n",
    "        #用户-Item关系矩阵R（内容同userEventScores相同），临时变量，训练完了R不再需要\n",
    "        R = np.zeros((self.n_users, self.n_events))\n",
    "    \n",
    "        for line in ftrain:\n",
    "            cols = line.strip().split(\",\")\n",
    "            u = self.userIndex[cols[0]]  #用户索引\n",
    "            i = self.eventIndex[cols[1]] #活动索引\n",
    "        \n",
    "            uids.append(u) # 添加到R矩阵中的用户索引列表\n",
    "            i_ids.append(i) # 添加到R矩阵中的用户索引列表\n",
    "            \n",
    "            R[u,i] = int(cols[4])  #interested\n",
    "            self.mu += R[u,i]\n",
    "            n_records += 1\n",
    "    \n",
    "        ftrain.close()\n",
    "        self.mu /= n_records\n",
    "    \n",
    "        # 请补充完整SVD模型训练过程\n",
    "        \n",
    "        for step in range(steps):\n",
    "            print('step',step+1,'is running')\n",
    "            rmse_sum = 0\n",
    "            kk = np.random.permutation(R.shape[0]) #随机梯度下降，每轮迭代随机打乱        \n",
    "            for j in range(R.shape[0]):  \n",
    "                #每次一个训练样本\n",
    "                index = kk[j]\n",
    "                u = uids[index]\n",
    "                i = i_ids[index]\n",
    "                \n",
    "                #预测残差\n",
    "                eui = R[u,i] - self.pred_SVD(u,i)\n",
    "                #残差平方和\n",
    "                rmse_sum+=eui**2\n",
    "            \n",
    "                #随机梯度下降，更新\n",
    "                self.bu[u]+= gamma*(eui - Lambda*self.bu[u])  \n",
    "                self.bi[i]+= gamma*(eui - Lambda*self.bi[i]) \n",
    "                \n",
    "                for k in range(self.k):\n",
    "                    tmp = self.P[u,k]\n",
    "                    self.P[u,k] += gamma * eui * self.Q[k,i] - Lambda * self.P[u,k]\n",
    "                    self.Q[k,i] += gamma * eui * tmp - Lambda * self.Q[k,i]\n",
    "                \n",
    "            #学习率递减\n",
    "            gamma=gamma*0.93  \n",
    "            print('rmse is',np.sqrt(rmse_sum/R.shape[0]))   \n",
    "        print (\"SVD trained\")\n",
    "        \n",
    "    def pred_SVD(self, uid, i_id):\n",
    "        #根据当前参数，预测用户uid对Item（i_id）的打分        \n",
    "        ans=self.mu + self.bi[i_id] + self.bu[uid] + np.dot(self.P[uid,:],self.Q[:,i_id])  \n",
    "\n",
    "        #将打分范围控制在0-1之间\n",
    "        if ans>1:  \n",
    "            return 1  \n",
    "        elif ans<0:  \n",
    "            return 0\n",
    "        return ans  \n",
    "\n",
    "    def sim_cal_UserCF(self, uid1, uid2 ):\n",
    "        #请补充基于用户的协同过滤中的两个用户uid1和uid2之间的相似度（根据两个用户对item打分的相似度）\n",
    "        si={}  #有效item（两个用户均有打分的item）的集合\n",
    "        for item in self.eventsForUser[uid1]:  #uid1所有打过分的Item1\n",
    "            if item in self.eventsForUser[uid2]:  #如果uid2也对该Item打过分\n",
    "                si[item]=1  #item为一个有效item\n",
    "        \n",
    "        #print si\n",
    "        n=len(si)   #有效item数，有效item为即对uid对Item打过分，uid2也对Item打过分\n",
    "        if (n==0):  #没有共同打过分的item，相似度设为0？\n",
    "            similarity=0  \n",
    "            return similarity  \n",
    "        \n",
    "        #用户uid1打过分的所有有效的item\n",
    "        s1=np.array([self.userEventScores[uid1,item] for item in si])  \n",
    "        \n",
    "        #用户uid2打过分的所有有效的Item\n",
    "        s2=np.array([self.userEventScores[uid2,item] for item in si])  \n",
    "        \n",
    "        sum1=np.sum(s1)  \n",
    "        sum2=np.sum(s2)  \n",
    "        sum1Sq=np.sum(s1**2)  \n",
    "        sum2Sq=np.sum(s2**2)  \n",
    "        pSum=np.sum(s1*s2)  \n",
    "\n",
    "        #分子\n",
    "        num=pSum-(sum1*sum2/n)  \n",
    "\n",
    "        #分母\n",
    "        den=np.sqrt((sum1Sq-sum1**2/n)*(sum2Sq-sum2**2/n))  \n",
    "        if den==0:  \n",
    "            similarity=0  \n",
    "            return 0  \n",
    "        \n",
    "        similarity = num/den  \n",
    "        return similarity  \n",
    "    \n",
    "    def userCFReco(self, userId, eventId):\n",
    "        \"\"\"\n",
    "        根据User-based协同过滤，得到event的推荐度\n",
    "        基本的伪代码思路如下：\n",
    "        for item i\n",
    "          for every other user v that has a preference for i\n",
    "            compute similarity s between u and v\n",
    "            incorporate v's preference for i weighted by s into running aversge\n",
    "        return top items ranked by weighted average\n",
    "        \"\"\"\n",
    "        #请补充完整代码\n",
    "        u = self.userIndex[userId]\n",
    "        i = self.eventIndex[eventId]\n",
    "    \n",
    "        sim_accumulate=0.0  \n",
    "        rat_acc=0.0  \n",
    "\n",
    "        for user in self.usersForEvent[i]:  #对eventId打过分的所有用户\n",
    "            sim = self.sim_cal_UserCF(uid1 = user,uid2 = u)    #该user与uid之间的相似度\n",
    "            if sim == 0:continue  \n",
    "            rat_acc += sim * self.userEventScores[user,i]   #用户user对eventId的打分\n",
    "            sim_accumulate += sim  \n",
    "          \n",
    "        if sim_accumulate==0: #no same user rated,return average rates of the data  \n",
    "            return  self.mu  \n",
    "        ans = rat_acc/sim_accumulate  \n",
    "\n",
    "        #将打分范围控制在0-1之间\n",
    "        if ans>1:  \n",
    "            return 1  \n",
    "        elif ans<0:  \n",
    "            return 0 \n",
    "        return ans\n",
    "\n",
    "    def sim_cal_ItemCF(self, i_id1, i_id2):\n",
    "        #计算Item i_id1和i_id2之间的相似性\n",
    "        #请补充完整代码\n",
    "        si={}  #有效用户集合\n",
    "        for user in self.usersForEvent[i_id1]:  #所有对Item1打过分的的user\n",
    "            if user in self.usersForEvent[i_id2]:  #如果该用户对Item2也打过分\n",
    "                si[user]=1  #user为一个有效用用户\n",
    "        \n",
    "        n=len(si)   #有效用户数，有效用户为即对Item1打过分，也对Item2打过分\n",
    "        if (n==0):  #没有共同打过分的用户，相似度设为0？\n",
    "            return 0  \n",
    "        \n",
    "        #所有有效用户对Item1的打分\n",
    "        #i1 = self.eventIndex[i_id1]\n",
    "        #i2 = self.eventIndex[i_id2]\n",
    "        s1=np.array([self.userEventScores[u, i_id1] for u in si])  \n",
    "\n",
    "        #所有有效用户对Item2的打分\n",
    "        s2=np.array([self.userEventScores[u, i_id2] for u in si])  \n",
    "\n",
    "        sum1=np.sum(s1)  \n",
    "        sum2=np.sum(s2)  \n",
    "        sum1Sq=np.sum(s1**2)  \n",
    "        sum2Sq=np.sum(s2**2)  \n",
    "        pSum=np.sum(s1*s2)  \n",
    "\n",
    "        #分子\n",
    "        num=pSum-(sum1*sum2/n)  \n",
    "\n",
    "        #分母\n",
    "        den=np.sqrt((sum1Sq-sum1**2/n)*(sum2Sq-sum2**2/n))  \n",
    "        if den==0:  \n",
    "            return 0  \n",
    "\n",
    "        return num/den  \n",
    "            \n",
    "    def eventCFReco(self, userId, eventId):    \n",
    "        \"\"\"\n",
    "        根据基于物品的协同过滤，得到Event的推荐度\n",
    "        基本的伪代码思路如下：\n",
    "        for item i \n",
    "            for every item j tht u has a preference for\n",
    "                compute similarity s between i and j\n",
    "                add u's preference for j weighted by s to a running average\n",
    "        return top items, ranked by weighted average\n",
    "        \"\"\"\n",
    "        u = self.userIndex[userId]\n",
    "        i = self.eventIndex[eventId]\n",
    "\n",
    "        sim_accumulate=0.0  \n",
    "        rat_acc=0.0  \n",
    "                   \n",
    "        for item in self.eventsForUser[u]:  #用户uid打过分的所有Item\n",
    "        #i2 = self.eventIndex[item]\n",
    "            sim = self.sim_cal_ItemCF(item,i)    #该Item与i_id之间的相似度\n",
    "           \n",
    "            rat_acc += sim * self.userEventScores[u,item]  \n",
    "            sim_accumulate += sim  \n",
    "        \n",
    "        #print rat_acc,sim_accumulate  \n",
    "        if sim_accumulate==0: #no same user rated,return average rates of the data  \n",
    "            return  self.mu  \n",
    "\n",
    "        ans = rat_acc/sim_accumulate  \n",
    "\n",
    "        #将打分范围控制在0-1之间\n",
    "        if ans>1:  \n",
    "            return 1  \n",
    "        elif ans<0:  \n",
    "            return 0\n",
    "        return ans\n",
    "\n",
    "    def svdCFReco(self, userId, eventId):\n",
    "        #基于模型的协同过滤, SVD++/LFM\n",
    "        u = self.userIndex[userId]\n",
    "        i = self.eventIndex[eventId]\n",
    "\n",
    "        return self.pred_SVD(u,i)\n",
    "    \n",
    "    def userReco(self, userId, eventId):\n",
    "        \"\"\"\n",
    "        类似基于User-based协同过滤，只是用户之间的相似度由用户本身的属性得到，计算event的推荐度\n",
    "        基本的伪代码思路如下：\n",
    "        for item i\n",
    "          for every other user v that has a preference for i\n",
    "            compute similarity s between u and v\n",
    "            incorporate v's preference for i weighted by s into running aversge\n",
    "        return top items ranked by weighted average\n",
    "        \"\"\"\n",
    "        i = self.userIndex[userId]\n",
    "        j = self.eventIndex[eventId]\n",
    "\n",
    "        vs = self.userEventScores[:, j]\n",
    "        sims = self.userSimMatrix[i, :]\n",
    "\n",
    "        prod = sims * vs\n",
    "\n",
    "        try:\n",
    "            return prod[0, 0] - self.userEventScores[i, j]\n",
    "        except IndexError:\n",
    "            return 0\n",
    "        \n",
    "    def eventReco(self, userId, eventId):\n",
    "        \"\"\"\n",
    "        类似基于Item-based协同过滤，只是item之间的相似度由item本身的属性得到，计算Event的推荐度\n",
    "        基本的伪代码思路如下：\n",
    "        for item i \n",
    "          for every item j that u has a preference for\n",
    "            compute similarity s between i and j\n",
    "            add u's preference for j weighted by s to a running average\n",
    "        return top items, ranked by weighted average\n",
    "        \"\"\"\n",
    "        i = self.userIndex[userId]\n",
    "        j = self.eventIndex[eventId]\n",
    "        js = self.userEventScores[i, :]\n",
    "        psim = self.eventPropSim[:, j]\n",
    "        csim = self.eventContSim[:, j]\n",
    "        pprod = js * psim\n",
    "        cprod = js * csim\n",
    "\n",
    "        pscore = 0\n",
    "        cscore = 0\n",
    "        try:\n",
    "            pscore = pprod[0, 0] - self.userEventScores[i, j]\n",
    "        except IndexError:\n",
    "            pass\n",
    "        try:\n",
    "            cscore = cprod[0, 0] - self.userEventScores[i, j]\n",
    "        except IndexError:\n",
    "            pass\n",
    "        return pscore, cscore\n",
    "\n",
    "    def userPop(self, userId):\n",
    "        \"\"\"\n",
    "        基于用户的朋友个数来推断用户的社交程度\n",
    "        主要的考量是如果用户的朋友非常多，可能会更倾向于参加各种社交活动\n",
    "        \"\"\"\n",
    "        if userId in self.userIndex:\n",
    "            i = self.userIndex[userId]\n",
    "            try:\n",
    "                return self.numFriends[0, i]\n",
    "            except IndexError:\n",
    "                return 0\n",
    "        else:\n",
    "            return 0\n",
    "\n",
    "    def friendInfluence(self, userId):\n",
    "        \"\"\"\n",
    "        朋友对用户的影响\n",
    "        主要考虑用户所有的朋友中，有多少是非常喜欢参加各种社交活动/event的\n",
    "        用户的朋友圈如果都积极参与各种event，可能会对当前用户有一定的影响\n",
    "        \"\"\"\n",
    "        nusers = np.shape(self.userFriends)[1]\n",
    "        i = self.userIndex[userId]\n",
    "        return (self.userFriends[i, :].sum(axis=0) / nusers)[0,0]\n",
    "\n",
    "    def eventPop(self, eventId):\n",
    "        \"\"\"\n",
    "        本活动本身的热度\n",
    "        主要是通过参与的人数来界定的\n",
    "        \"\"\"\n",
    "        i = self.eventIndex[eventId]\n",
    "        return self.eventPopularity[i, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generateRSData(RS, train=True, header=True):\n",
    "    \"\"\"\n",
    "    把前面user-based协同过滤 和 item-based协同过滤，以及各种热度和影响度作为特征组合在一起\n",
    "    生成新的训练数据，用于分类器分类使用\n",
    "    \"\"\"\n",
    "    fn = \"train.csv\" if train else \"test.csv\"\n",
    "    path = '/Users/cuiyue/Desktop/AI/第四周/作业/要求/71-57-1-1519640547/'\n",
    "    fin = open(path + fn, 'rb')\n",
    "    fout = open(\"RS_\" + fn, 'w')\n",
    "    \n",
    "    #忽略第一行（列名字）\n",
    "    fin.readline().decode('utf-8').strip().split(\",\")\n",
    "    \n",
    "    \n",
    "    # write output header\n",
    "    if header:\n",
    "        ocolnames = [\"invited\", \"userCF_reco\", \"evtCF_reco\",\"svdCF_reco\",\"user_reco\", \"evt_p_reco\",\"evt_c_reco\", \"user_pop\", \"frnd_infl\", \"evt_pop\"]\n",
    "    if train:\n",
    "        ocolnames.append(\"interested\")\n",
    "        ocolnames.append(\"not_interested\")\n",
    "        fout.write(\",\".join(ocolnames) + \"\\n\")\n",
    "        \n",
    "    ln = 0\n",
    "    for line in fin:\n",
    "        cols = line.decode('utf-8').strip().split(\",\")\n",
    "        userId = cols[0]\n",
    "        eventId = cols[1]\n",
    "        invited = cols[2]\n",
    "       \n",
    "        ln += 1\n",
    "        if ln%500 == 0:\n",
    "            print( \"%s:%d (userId, eventId)=(%s, %s)\" % (fn, ln, userId, eventId))\n",
    "          #break;\n",
    "        \n",
    "    userCF_reco = RS.userCFReco(userId, eventId)\n",
    "    itemCF_reco = RS.eventCFReco(userId, eventId)\n",
    "    svdCF_reco = RS.svdCFReco(userId, eventId)\n",
    "        \n",
    "    user_reco = RS.userReco(userId, eventId)\n",
    "    evt_p_reco, evt_c_reco = RS.eventReco(userId, eventId)\n",
    "    user_pop = RS.userPop(userId)\n",
    "\n",
    "    frnd_infl = RS.friendInfluence(userId)\n",
    "    evt_pop = RS.eventPop(eventId)\n",
    "    ocols = [invited, userCF_reco, itemCF_reco, svdCF_reco,user_reco, evt_p_reco,\n",
    "    evt_c_reco, user_pop, frnd_infl, evt_pop]\n",
    "      \n",
    "    if train:\n",
    "        ocols.append(cols[4]) # interested\n",
    "        ocols.append(cols[5]) # not_interested\n",
    "        fout.write(\",\".join(map(lambda x: str(x), ocols)) + \"\\n\")\n",
    "    \n",
    "    fin.close()\n",
    "    fout.close()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SVD Train...\n",
      "step 1 is running\n",
      "rmse is 0.6470452766791179\n",
      "step 2 is running\n",
      "rmse is 0.42092479573315184\n",
      "step 3 is running\n",
      "rmse is 0.39776275456498467\n",
      "step 4 is running\n",
      "rmse is 0.3829406879297765\n",
      "step 5 is running\n",
      "rmse is 0.37061619474495155\n",
      "step 6 is running\n",
      "rmse is 0.36026435319302447\n",
      "step 7 is running\n",
      "rmse is 0.35157611211399253\n",
      "step 8 is running\n",
      "rmse is 0.34451006853730504\n",
      "step 9 is running\n",
      "rmse is 0.338112029366448\n",
      "step 10 is running\n",
      "rmse is 0.33256593849476124\n",
      "step 11 is running\n",
      "rmse is 0.3276478059757922\n",
      "step 12 is running\n",
      "rmse is 0.32326496890237916\n",
      "step 13 is running\n",
      "rmse is 0.31933541357010775\n",
      "step 14 is running\n",
      "rmse is 0.3158158849845741\n",
      "step 15 is running\n",
      "rmse is 0.3126958671834772\n",
      "step 16 is running\n",
      "rmse is 0.3098308339232669\n",
      "step 17 is running\n",
      "rmse is 0.3072987881926106\n",
      "step 18 is running\n",
      "rmse is 0.3048711962341161\n",
      "step 19 is running\n",
      "rmse is 0.3027534388921611\n",
      "step 20 is running\n",
      "rmse is 0.30076641889447425\n",
      "step 21 is running\n",
      "rmse is 0.29905031035662044\n",
      "step 22 is running\n",
      "rmse is 0.29738290934282474\n",
      "step 23 is running\n",
      "rmse is 0.2958665204529885\n",
      "step 24 is running\n",
      "rmse is 0.29448676121354544\n",
      "step 25 is running\n",
      "rmse is 0.29325495948050434\n",
      "step 26 is running\n",
      "rmse is 0.29211877969768374\n",
      "step 27 is running\n",
      "rmse is 0.291058644119581\n",
      "step 28 is running\n",
      "rmse is 0.2900903561266721\n",
      "step 29 is running\n",
      "rmse is 0.28919409896447296\n",
      "step 30 is running\n",
      "rmse is 0.28836399299072407\n",
      "step 31 is running\n",
      "rmse is 0.2875999253944556\n",
      "step 32 is running\n",
      "rmse is 0.2868945442787156\n",
      "step 33 is running\n",
      "rmse is 0.28624796005291464\n",
      "step 34 is running\n",
      "rmse is 0.28565927392778934\n",
      "step 35 is running\n",
      "rmse is 0.2850956834402697\n",
      "step 36 is running\n",
      "rmse is 0.28457966753232466\n",
      "step 37 is running\n",
      "rmse is 0.2840772347804237\n",
      "step 38 is running\n",
      "rmse is 0.2836523851162918\n",
      "step 39 is running\n",
      "rmse is 0.28323897662382813\n",
      "step 40 is running\n",
      "rmse is 0.2828722715403982\n",
      "step 41 is running\n",
      "rmse is 0.28252524988795574\n",
      "step 42 is running\n",
      "rmse is 0.28220820579042416\n",
      "step 43 is running\n",
      "rmse is 0.2819031800258111\n",
      "step 44 is running\n",
      "rmse is 0.2816247191345308\n",
      "step 45 is running\n",
      "rmse is 0.28135170763960504\n",
      "step 46 is running\n",
      "rmse is 0.28113114094866326\n",
      "step 47 is running\n",
      "rmse is 0.28090457625090864\n",
      "step 48 is running\n",
      "rmse is 0.2806911456379424\n",
      "step 49 is running\n",
      "rmse is 0.28051077371897915\n",
      "step 50 is running\n",
      "rmse is 0.2803269212600718\n",
      "step 51 is running\n",
      "rmse is 0.28016362707801046\n",
      "step 52 is running\n",
      "rmse is 0.2800118336939648\n",
      "step 53 is running\n",
      "rmse is 0.27987179939280366\n",
      "step 54 is running\n",
      "rmse is 0.2797389843337427\n",
      "step 55 is running\n",
      "rmse is 0.2796109947464128\n",
      "step 56 is running\n",
      "rmse is 0.27950178864485287\n",
      "step 57 is running\n",
      "rmse is 0.2793992842082194\n",
      "step 58 is running\n",
      "rmse is 0.2792988795614798\n",
      "step 59 is running\n",
      "rmse is 0.2792045988372806\n",
      "step 60 is running\n",
      "rmse is 0.27912091055364324\n",
      "step 61 is running\n",
      "rmse is 0.2790446655102906\n",
      "step 62 is running\n",
      "rmse is 0.2789714088479839\n",
      "step 63 is running\n",
      "rmse is 0.27890488800807545\n",
      "step 64 is running\n",
      "rmse is 0.2788382661607729\n",
      "step 65 is running\n",
      "rmse is 0.2787795953611453\n",
      "step 66 is running\n",
      "rmse is 0.27872703610358535\n",
      "step 67 is running\n",
      "rmse is 0.2786765366192296\n",
      "step 68 is running\n",
      "rmse is 0.2786290151327355\n",
      "step 69 is running\n",
      "rmse is 0.27858705271099926\n",
      "step 70 is running\n",
      "rmse is 0.27854336210826014\n",
      "step 71 is running\n",
      "rmse is 0.27850593602765483\n",
      "step 72 is running\n",
      "rmse is 0.27847260751592934\n",
      "step 73 is running\n",
      "rmse is 0.27844038285670814\n",
      "step 74 is running\n",
      "rmse is 0.27840918687172983\n",
      "step 75 is running\n",
      "rmse is 0.2783811764640289\n",
      "step 76 is running\n",
      "rmse is 0.27835557782092396\n",
      "step 77 is running\n",
      "rmse is 0.27833152252436877\n",
      "step 78 is running\n",
      "rmse is 0.2783083069303425\n",
      "step 79 is running\n",
      "rmse is 0.27828669300760783\n",
      "step 80 is running\n",
      "rmse is 0.27826730951120127\n",
      "step 81 is running\n",
      "rmse is 0.27824878001613057\n",
      "step 82 is running\n",
      "rmse is 0.27823169815392673\n",
      "step 83 is running\n",
      "rmse is 0.27821621587245354\n",
      "step 84 is running\n",
      "rmse is 0.2782017406204425\n",
      "step 85 is running\n",
      "rmse is 0.2781880416954725\n",
      "step 86 is running\n",
      "rmse is 0.2781754228658821\n",
      "step 87 is running\n",
      "rmse is 0.27816401351331926\n",
      "step 88 is running\n",
      "rmse is 0.2781526263910338\n",
      "step 89 is running\n",
      "rmse is 0.278142697763825\n",
      "step 90 is running\n",
      "rmse is 0.27813282378071696\n",
      "step 91 is running\n",
      "rmse is 0.2781240514573488\n",
      "step 92 is running\n",
      "rmse is 0.2781159719796756\n",
      "step 93 is running\n",
      "rmse is 0.27810830872447995\n",
      "step 94 is running\n",
      "rmse is 0.27810136676305597\n",
      "step 95 is running\n",
      "rmse is 0.27809505085284064\n",
      "step 96 is running\n",
      "rmse is 0.2780885858165928\n",
      "step 97 is running\n",
      "rmse is 0.278083103485101\n",
      "step 98 is running\n",
      "rmse is 0.27807786798248885\n",
      "step 99 is running\n",
      "rmse is 0.2780723259815273\n",
      "step 100 is running\n",
      "rmse is 0.27806822026092126\n",
      "SVD trained\n",
      "生成训练数据...\n",
      "\n",
      "train.csv:500 (userId, eventId)=(127904873, 2529072432)\n",
      "train.csv:1000 (userId, eventId)=(272886293, 3264448398)\n",
      "train.csv:1500 (userId, eventId)=(395305791, 3139200527)\n",
      "train.csv:2000 (userId, eventId)=(527523423, 1616400535)\n",
      "train.csv:2500 (userId, eventId)=(651258472, 3469146752)\n",
      "train.csv:3000 (userId, eventId)=(811791433, 4181313745)\n",
      "train.csv:3500 (userId, eventId)=(985547042, 236468864)\n",
      "train.csv:4000 (userId, eventId)=(1107615001, 2530713176)\n",
      "train.csv:4500 (userId, eventId)=(1239364869, 1320373094)\n",
      "train.csv:5000 (userId, eventId)=(1414301782, 3466325304)\n",
      "train.csv:5500 (userId, eventId)=(1595465532, 1600413013)\n",
      "train.csv:6000 (userId, eventId)=(1747091728, 1935724864)\n",
      "train.csv:6500 (userId, eventId)=(1914182220, 3632072502)\n",
      "train.csv:7000 (userId, eventId)=(2071842684, 2007279414)\n",
      "train.csv:7500 (userId, eventId)=(2217853337, 33770938)\n",
      "train.csv:8000 (userId, eventId)=(2338481531, 1355652628)\n",
      "train.csv:8500 (userId, eventId)=(2489943153, 1709116685)\n",
      "train.csv:9000 (userId, eventId)=(2650493630, 2465528861)\n",
      "train.csv:9500 (userId, eventId)=(2791418962, 130493588)\n",
      "train.csv:10000 (userId, eventId)=(2903662804, 4114116369)\n",
      "train.csv:10500 (userId, eventId)=(3036141956, 3388135408)\n",
      "train.csv:11000 (userId, eventId)=(3176074542, 1629566665)\n",
      "train.csv:11500 (userId, eventId)=(3285425249, 2827139478)\n",
      "train.csv:12000 (userId, eventId)=(3410667855, 3934491209)\n",
      "train.csv:12500 (userId, eventId)=(3531604778, 521858421)\n",
      "train.csv:13000 (userId, eventId)=(3686871863, 2633637786)\n",
      "train.csv:13500 (userId, eventId)=(3833637800, 2130616732)\n",
      "train.csv:14000 (userId, eventId)=(3944021305, 1159558718)\n",
      "train.csv:14500 (userId, eventId)=(4075466480, 3463618172)\n",
      "train.csv:15000 (userId, eventId)=(4197193550, 2582345152)\n",
      "生成预测数据...\n",
      "\n",
      "test.csv:500 (userId, eventId)=(182290053, 2643833505)\n",
      "test.csv:1000 (userId, eventId)=(436276762, 673098017)\n",
      "test.csv:1500 (userId, eventId)=(632808865, 3122144172)\n",
      "test.csv:2000 (userId, eventId)=(813611885, 1137824063)\n",
      "test.csv:2500 (userId, eventId)=(1010701404, 2042242482)\n",
      "test.csv:3000 (userId, eventId)=(1210932037, 1390707377)\n",
      "test.csv:3500 (userId, eventId)=(1452921099, 2454443883)\n",
      "test.csv:4000 (userId, eventId)=(1623287180, 2678645214)\n",
      "test.csv:4500 (userId, eventId)=(1855201342, 3883276816)\n",
      "test.csv:5000 (userId, eventId)=(2083900381, 2090707728)\n",
      "test.csv:5500 (userId, eventId)=(2320854059, 1231257462)\n",
      "test.csv:6000 (userId, eventId)=(2528161539, 2354857659)\n",
      "test.csv:6500 (userId, eventId)=(2749110768, 1741327284)\n",
      "test.csv:7000 (userId, eventId)=(2927772127, 364572656)\n",
      "test.csv:7500 (userId, eventId)=(3199685636, 1765678116)\n",
      "test.csv:8000 (userId, eventId)=(3393388475, 766696037)\n",
      "test.csv:8500 (userId, eventId)=(3601169721, 1006504281)\n",
      "test.csv:9000 (userId, eventId)=(3828963415, 2618008446)\n",
      "test.csv:9500 (userId, eventId)=(4018723397, 2251036191)\n",
      "test.csv:10000 (userId, eventId)=(4180064266, 714156115)\n"
     ]
    }
   ],
   "source": [
    "RS = RecommonderSystem()\n",
    "print (\"生成训练数据...\\n\")\n",
    "generateRSData(RS,train=True,  header=True)\n",
    "\n",
    "print (\"生成预测数据...\\n\")\n",
    "generateRSData(RS, train=False, header=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
